From c70c677b5a4395ff0c5983da0a28ee60b1da9aa6 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Tue, 2 Apr 2019 20:49:35 +0100 Subject: [PATCH] Add GtkFixed demo This demo has everything: - a GtkFixed inside another GtkFixed - a cube made out of GtkFrame widgets - an example of 3D transformations And what's there, in the window once I launch it? The GTK logo made of widgets. --- demos/gtk-demo/demo.gresource.xml | 4 + demos/gtk-demo/fixed.c | 167 ++++++++++++++++++++++++++++++ demos/gtk-demo/fixed.css | 29 ++++++ demos/gtk-demo/meson.build | 1 + 4 files changed, 201 insertions(+) create mode 100644 demos/gtk-demo/fixed.c create mode 100644 demos/gtk-demo/fixed.css diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index 051161242c..a71adcee26 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -163,6 +163,7 @@ expander.c filtermodel.c fishbowl.c + fixed.c flowbox.c foreigndrawing.c font_features.c @@ -270,6 +271,9 @@ demotaggedentry.c demotaggedentry.h + + fixed.css + icons/16x16/actions/application-exit.png icons/16x16/actions/document-new.png diff --git a/demos/gtk-demo/fixed.c b/demos/gtk-demo/fixed.c new file mode 100644 index 0000000000..745b8c7288 --- /dev/null +++ b/demos/gtk-demo/fixed.c @@ -0,0 +1,167 @@ +/* Fixed layout + * + * GtkFixed is a container that allows placing and transforming + * widgets manually. + */ + +#include + +/* This enumeration determines the paint order */ +enum { + FACE_BACK, + FACE_LEFT, + FACE_BOTTOM, + FACE_RIGHT, + FACE_TOP, + FACE_FRONT, + + N_FACES +}; + +/* Map face widgets to CSS classes */ +static struct { + GtkWidget *face; + const char *css_class; +} faces[N_FACES] = { + [FACE_BACK] = { NULL, "back", }, + [FACE_LEFT] = { NULL, "left", }, + [FACE_RIGHT] = { NULL, "right", }, + [FACE_TOP] = { NULL, "top", }, + [FACE_BOTTOM] = { NULL, "bottom", }, + [FACE_FRONT] = { NULL, "front", }, +}; + +static GtkWidget * +create_faces (void) +{ + GtkWidget *fixed = gtk_fixed_new (); + int face_size = 200; + float w, h, d, p; + + gtk_widget_set_overflow (fixed, GTK_OVERFLOW_VISIBLE); + + w = (float) face_size / 2.f; + h = (float) face_size / 2.f; + d = (float) face_size / 2.f; + p = face_size * 3.f; + + for (int i = 0; i < N_FACES; i++) + { + GskTransform *transform = NULL; + + /* Add a face */ + faces[i].face = gtk_frame_new (NULL); + gtk_widget_set_size_request (faces[i].face, face_size, face_size); + gtk_style_context_add_class (gtk_widget_get_style_context (faces[i].face), faces[i].css_class); + gtk_container_add (GTK_CONTAINER (fixed), faces[i].face); + + /* Set up the transformation for each face */ + transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (w, h)); + transform = gsk_transform_perspective (transform, p); + transform = gsk_transform_rotate_3d (transform, -30.f, graphene_vec3_x_axis ()); + transform = gsk_transform_rotate_3d (transform, 135.f, graphene_vec3_y_axis ()); + transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0, 0, -face_size / 6.f)); + + switch (i) + { + case FACE_FRONT: + transform = gsk_transform_rotate_3d (transform, 0.f, graphene_vec3_y_axis ()); + break; + + case FACE_BACK: + transform = gsk_transform_rotate_3d (transform, -180.f, graphene_vec3_y_axis ()); + break; + + case FACE_RIGHT: + transform = gsk_transform_rotate_3d (transform, 90.f, graphene_vec3_y_axis ()); + break; + + case FACE_LEFT: + transform = gsk_transform_rotate_3d (transform, -90.f, graphene_vec3_y_axis ()); + break; + + case FACE_TOP: + transform = gsk_transform_rotate_3d (transform, 90.f, graphene_vec3_x_axis ()); + break; + + case FACE_BOTTOM: + transform = gsk_transform_rotate_3d (transform, -90.f, graphene_vec3_x_axis ()); + break; + + default: + break; + } + + transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0, 0, d)); + transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (-w, -h, 0)); + + gtk_fixed_set_child_transform (GTK_FIXED (fixed), faces[i].face, transform); + gsk_transform_unref (transform); + } + + return fixed; +} + +static GtkWidget *demo_window = NULL; +static GtkCssProvider *provider = NULL; + +static void +close_window (GtkWidget *widget) +{ + /* Reset the state */ + for (int i = 0; i < N_FACES; i++) + faces[i].face = NULL; + + gtk_style_context_remove_provider_for_display (gdk_display_get_default (), + GTK_STYLE_PROVIDER (provider)); + provider = NULL; + + demo_window = NULL; +} + +static GtkWidget * +create_demo_window (GtkWidget *do_widget) +{ + GtkWidget *window, *sw, *fixed, *cube; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget)); + gtk_window_set_title (GTK_WINDOW (window), "Fixed layout"); + gtk_window_set_default_size (GTK_WINDOW (window), 600, 400); + g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL); + + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (window), sw); + + fixed = gtk_fixed_new (); + gtk_container_add (GTK_CONTAINER (sw), fixed); + gtk_widget_set_halign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER); + gtk_widget_set_valign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER); + + cube = create_faces (); + gtk_container_add (GTK_CONTAINER (fixed), cube); + gtk_widget_set_overflow (fixed, GTK_OVERFLOW_VISIBLE); + + provider = gtk_css_provider_new (); + gtk_css_provider_load_from_resource (provider, "/fixed/fixed.css"); + gtk_style_context_add_provider_for_display (gdk_display_get_default (), + GTK_STYLE_PROVIDER (provider), + 800); + g_object_unref (provider); + + return window; +} + +GtkWidget* +do_fixed (GtkWidget *do_widget) +{ + if (demo_window == NULL) + demo_window = create_demo_window (do_widget); + + if (!gtk_widget_get_visible (demo_window)) + gtk_widget_show (demo_window); + else + gtk_widget_destroy (demo_window); + + return demo_window; +} diff --git a/demos/gtk-demo/fixed.css b/demos/gtk-demo/fixed.css new file mode 100644 index 0000000000..0e62285e19 --- /dev/null +++ b/demos/gtk-demo/fixed.css @@ -0,0 +1,29 @@ +frame.front { + border: 2px solid white; + background-color: rgba(228, 0, 0, 0.8); +} + +frame.back { + border: 2px solid white; + background-color: rgba(228, 0, 0, 0.8); +} + +frame.right { + border: 2px solid white; + background-color: rgba(127, 231, 25, 0.8); +} + +frame.left { + border: 2px solid white; + background-color: rgba(127, 231, 25, 0.8); +} + +frame.top { + border: 2px solid white; + background-color: rgba(114, 159, 207, 0.8); +} + +frame.bottom { + border: 2px solid white; + background-color: rgba(114, 159, 207, 0.8); +} diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build index cbe956d0c2..aba44c976c 100644 --- a/demos/gtk-demo/meson.build +++ b/demos/gtk-demo/meson.build @@ -24,6 +24,7 @@ demos = files([ 'expander.c', 'filtermodel.c', 'fishbowl.c', + 'fixed.c', 'foreigndrawing.c', 'gestures.c', 'glarea.c', -- 2.30.2